package org.lex.ftplist.core.diff;

import java.util.Collection;
import java.util.List;

import org.apache.commons.net.ftp.FTPFile;
import org.lex.collection.tree.ITreeNode;
import org.lex.collection.tree.diff.AbstractNodeComparator;
import org.lex.collection.tree.diff.Diff;
import org.lex.collection.tree.diff.DiffSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FTPNodeComparator extends AbstractNodeComparator {
	private Logger log = LoggerFactory.getLogger(FTPNodeComparator.class);

	@Override
	public boolean isUpdate(Diff<ITreeNode> diff) {
		FTPFile oldFile = (FTPFile) diff.oldObject.getData();
		FTPFile newFile = (FTPFile) diff.newObject.getData();
		boolean update = oldFile.getSize() != newFile.getSize();
		update = update || false == oldFile.getName().equals(newFile.getName());
		update = update || oldFile.getTimestamp().getTimeInMillis() != newFile.getTimestamp().getTimeInMillis();
		return update;
	}

	public DiffSet compareNodes(DiffSet results, List<ITreeNode> oldNodes, List<ITreeNode> newNodes) {
		for (ITreeNode oldNode : oldNodes) {
			ITreeNode newNode = this.findNode(oldNode, newNodes);
			log.info("old=[" + oldNode + "], new=[" + newNode + "]");
			if (null == newNode) {
				results.deleted.add(oldNode);
			} else {
				results.addSameOrUpdated(oldNode, newNode);
				newNodes.remove(newNode);
			}
		}
		results.added.addAll(newNodes);
		return results;
	}

	/**
	 * find an ITreeNode from <code>source</code>, who has the same type, and
	 * same name wigh <code>target</code>
	 * 
	 * @param target
	 * @param source
	 */
	private ITreeNode findNode(ITreeNode target, Collection<ITreeNode> source) {
		FTPFile targetFile = (FTPFile) target.getData();
		boolean isFile = targetFile.isFile();
		boolean isDir = targetFile.isDirectory();
		String name = targetFile.getName();

		for (ITreeNode src : source) {
			FTPFile file = (FTPFile) src.getData();
			if (file.isFile() == isFile && file.isDirectory() == isDir && file.getName().equals(name)) {
				return src;
			}
		}
		return null;
	}
}
